﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Timers;

namespace ComHelper
{
    public partial class Form1 : Form
    {
        //设置全局变量；
        SerialPort port1 ;
        System.Timers.Timer timer = new System.Timers.Timer();
        
        public Form1()
        {
            InitializeComponent();
        }


        /**
         * 窗体加载
         */
        private void Form1_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            port1 = new SerialPort();
            port1.DataReceived += new SerialDataReceivedEventHandler(port1_DataReceived);
            //初始化界面参数
            sendhex_rb.Checked = false;
            sendchar_rb.Checked = true;
            receivechar_rb.Checked = true;
            receivehex_rb.Checked = false;
            //读取配置文件
            String basePath = AppDomain.CurrentDomain.BaseDirectory;
            String pathstr = basePath + "cfg.ini";
            try
            {
                OpPrivateProfiles op = new OpPrivateProfiles(pathstr);

                //    String portNameStr = op.iniReadFile("config","defaultport");
                String baudbitStr = op.iniReadFile("config", "baudrate");
                String databitStr = op.iniReadFile("config", "databits");
                String stopbitStr = op.iniReadFile("config", "stopbits");
                String parityStr = op.iniReadFile("config", "parity");

                //    port_cb.Text = portNameStr;
                baudrate_cb.Text = baudbitStr;
                databit_cb.Text  = databitStr;
                stopbit_cb.Text  = stopbitStr;
                paritybit_cb.Text  = parityStr;
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取配置参数失败！");
            }
            

        

            baudrate_cb.Items.Add(9600);
            baudrate_cb.Items.Add(19200);
            baudrate_cb.Items.Add(38400);
            baudrate_cb.Items.Add(57600);
            baudrate_cb.Items.Add(115200);

            databit_cb.Items.Add(5);
            databit_cb.Items.Add(6);
            databit_cb.Items.Add(7);
            databit_cb.Items.Add(8);

            stopbit_cb.Items.Add(1);
            stopbit_cb.Items.Add(1.5);
            stopbit_cb.Items.Add(2);

            paritybit_cb.Items.Add("none");
            paritybit_cb.Items.Add("odd");
            paritybit_cb.Items.Add("even");
            /**
             * 检查计算机是否含有串口
             * 
             */
            String[] portstr = SerialPort.GetPortNames();
            if (portstr.Length == 0)
            {
                MessageBox.Show("未检测到串口！", "Error");
                return;
            }
            
            //添加串口项目
            foreach (string s in System.IO.Ports.SerialPort.GetPortNames())
            {
                port_cb.Items.Add(s);              
            }     
            
        }

        /**
         * 打开串口设置
         */
        private void portopen_btn_Click(object sender, EventArgs e)
        {

            if (string.IsNullOrEmpty(port_cb.Text.Trim()))
            {
                MessageBox.Show("未选择串口！");
            }
            else
            {
                if (!port1.IsOpen)
                {
                    try
                    {
                        //设置串口号
                        String serialName = port_cb.SelectedItem.ToString();
                        port1.PortName = serialName;

                        //设置串口参数
                        String baudrateStr = baudrate_cb.Text;
                        String databitStr = databit_cb.Text;
                        String stopbitStr = stopbit_cb.Text;
                        String paritybitStr = paritybit_cb.Text;
                        //字符串转数值
                        Int32 baudrateInt = Convert.ToInt32(baudrateStr);
                        Int32 databitInt = Convert.ToInt32(databitStr);
                        //波特率，数据位
                        port1.BaudRate = baudrateInt;
                        port1.DataBits = databitInt;
                        //停止位
                        switch (stopbitStr)
                        {
                            case "1":
                                port1.StopBits = StopBits.One;
                                break;
                            case "1.5":
                                port1.StopBits = StopBits.OnePointFive;
                                break;
                            case "2":
                                port1.StopBits = StopBits.Two;
                                break;
                            default:
                                MessageBox.Show("参数不正确！");
                                break;
                        }
                        //校验位
                        switch (paritybitStr)
                        {
                            case "none":
                                port1.Parity = Parity.None;
                                break;
                            case "odd":
                                port1.Parity = Parity.Odd;
                                break;
                            case "even":
                                port1.Parity = Parity.Even;
                                break;
                            default:
                                MessageBox.Show("参数不正确！");
                                break;
                        }

                        if (port1.IsOpen == true)
                        {
                            port1.Close();
                        }

                        //状态栏设置
                        portnum_lb.Text = port1.PortName;
                        baudrate_lb.Text = port1.BaudRate + "";
                        databit_lb.Text = port1.DataBits + "";
                        stopbit_lb.Text = port1.StopBits + "";
                        paritybit_lb.Text = port1.Parity + "";

                        //设置必要控件状态
                        port_cb.Enabled = false;
                        baudrate_cb.Enabled = false;
                        databit_cb.Enabled = false;
                        stopbit_cb.Enabled = false;
                        paritybit_cb.Enabled = false;

                        //打开串口
                        port1.Open();
                        portopen_btn.Text = "关闭串口";

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:" + ex.Message);
                        //设置必要控件状态
                        port_cb.Enabled = true;
                        baudrate_cb.Enabled = true;
                        databit_cb.Enabled = true;
                        stopbit_cb.Enabled = true;
                        paritybit_cb.Enabled = true;
                    }
                }
                else
                {
                    
                    //状态栏设置
                    portnum_lb.Text = "未指定";
                    baudrate_lb.Text = "未指定";
                    databit_lb.Text = "未指定";
                    stopbit_lb.Text = "未指定";
                    paritybit_lb.Text = "未指定";

                    //设置必要控件状态
                    port_cb.Enabled = true;
                    baudrate_cb.Enabled = true;
                    databit_cb.Enabled = true;
                    stopbit_cb.Enabled = true;
                    paritybit_cb.Enabled = true;

                    //关闭串口
                    try
                    {
                        port1.Close();
                        if (timer.Enabled == true)
                        {
                            timer.Stop();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:定时发送关闭失败！" + ex.Message);
                    }
                    portopen_btn.Text = "打开串口";
                }

            }         
            
        }

        /**
         * 发送数据
         */
        private void datasend_btn_Click(object sender, EventArgs e)
        {
            if (!port1.IsOpen)
            {
                MessageBox.Show("请打开串口");
                return;
            }

            //获取发送数据；
            String sendStr = datasend_tb.Text;

            //字符串发送
            if (sendchar_rb.Checked)
            {
                port1.WriteLine(sendStr);
                port1.DiscardInBuffer();

            }
            //16进制发送
            else if (sendhex_rb.Checked)
            {
                String sendBuf = strToHex(sendStr.Trim(),Encoding.ASCII);
                port1.WriteLine(sendBuf);
                port1.DiscardInBuffer();

            }
            //其他
            else
            {
                MessageBox.Show("请选择唯一的发送数据格式");
            }
        }

        /**
         * 字符串转16进制(ascii)
         */
        private static String strToHex(string s, Encoding encode)
        {
            //按照指定编码将字符串变为字符数组；
            byte[] b = encode.GetBytes(s);
            String result = string.Empty;
            for (int i = 0; i < b.Length; i++)
            {
                result = result + "%" + Convert.ToString(b[i], 16);
            }
            return result;
        }

        private static String hexToString(byte[] hexarray, Encoding encode)
        {
            String result = string.Empty;
            result = encode.GetString(hexarray);

            return result;
        }

        /**
         * 重载方法
         */
        private void port1_DataReceived(Object sender,SerialDataReceivedEventArgs e)
        {
            if (port1.IsOpen)
            {
                      

                //发送方是字符串的处理方法
                if (sendhex_rb.Checked)
                {
                    String receivedData_str = null;
                    receivedData_str +=  port1.ReadLine() + "\r\n";
                    port1.DiscardInBuffer();
                    //接收方的显示方式
                    //16进制显示
                    if (receivehex_rb.Checked)
                    {
                        receivedData_str = strToHex(receivedData_str, Encoding.ASCII);
                        datareceive_tb.Text += receivedData_str + "\t";
                    }
                    //字符串显示
                    else
                    {
                        datareceive_tb.Text += receivedData_str + "\t";
                    }
                }
                //发送方是16进制的处理方法
                else
                {
                    try
                    {
                        String receivedData_hex = null;
                        String rehexstr = null;
                        //接收字符个数数组
                        byte[] byteRead = new byte[port1.BytesToRead];
                        port1.Read(byteRead, 0, byteRead.Length);
                        port1.DiscardInBuffer();

                        for (int i = 0; i < byteRead.Length; i++)
                        {
                            rehexstr += byteRead[i];
                            if ((i+1) % 2 == 0)
                            {
                                rehexstr += "\t"; 
                            }
                            
                        }
                        receivedData_hex = rehexstr;

                        //接收方的显示方式
                        //16进制显示
                        if (receivehex_rb.Checked)
                        {
                            datareceive_tb.Text += receivedData_hex + "\t";
                        }
                        //字符串显示
                        else
                        {
                            receivedData_hex = hexToString(byteRead, Encoding.ASCII);
                            datareceive_tb.Text += receivedData_hex + "\t";
                        }

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:" + ex.Message);
                    }

                }   

            }
        }
        /**
         * 保存参数设置； 
         */
        private void save_btn_Click(object sender, EventArgs e)
        {
            String basePath = AppDomain.CurrentDomain.BaseDirectory;
            String pathstr = basePath + "cfg.ini";
            OpPrivateProfiles op = new OpPrivateProfiles(pathstr);

          //  op.iniWriteFile("config", "defaultport", port_cb.Text);
            op.iniWriteFile("config", "baudrate", baudrate_cb.Text);
            op.iniWriteFile("config", "databits", databit_cb.Text);
            op.iniWriteFile("config", "stopbits", stopbit_cb.Text);
            op.iniWriteFile("config", "parity", paritybit_cb.Text);

        }

        private void dataclear_btn_Click(object sender, EventArgs e)
        {
            datareceive_tb.Text = null;
           
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            MessageBoxButtons messButton = MessageBoxButtons.OKCancel;
            DialogResult dr = MessageBox.Show("确定要退出吗？", "退出系统", messButton);

            if (dr == DialogResult.OK)
            {
                if (port1.IsOpen)
                {                   
                    try
                    {
                        port1.Close();
                        if (timer.Enabled == true)
                        {
                            timer.Stop();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:定时发送关闭失败！" + ex.Message);
                    }
                }

                System.Environment.Exit(0);
            }
            
        }

        private void timersend_ck_CheckStateChanged(object sender, EventArgs e)
        {
            if (timersend_ck.Checked)
            {
                //定时发送
                string intervaltime = interval_tb.Text;
                if (string.IsNullOrEmpty(intervaltime))
                {
                    MessageBox.Show("请选择定时时间间隔");
                }
                else
                {
                    try
                    {
                        int secondin = int.Parse(intervaltime) * 1000;
                        timer.Interval = secondin;
                        timer.AutoReset = true;
                        timer.Elapsed += myTimer_Elapsed;
                        timer.Enabled = true;
                        
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:" + ex.Message);
                    }
                }
                

                
            }
            else
            {
                try
                {
                    if (timer.Enabled == true)
                    {
                        timer.Stop();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error:定时发送关闭失败！" + ex.Message);
                }
            }
        }

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (timer.Enabled == true)
            {
                datasend_btn.PerformClick();
            }
        }

        private void interval_tb_TextChanged(object sender, EventArgs e)
        {

        }

        private void timersend_ck_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void exit_btn_Click(object sender, EventArgs e)
        {
            MessageBoxButtons messButton = MessageBoxButtons.OKCancel;
            DialogResult dr = MessageBox.Show("确定要退出吗？", "退出系统", messButton);

            if (dr == DialogResult.OK)
            {
                if (port1.IsOpen)
                {
                    try
                    {
                        port1.Close();
                        if (timer.Enabled == true)
                        {
                            timer.Stop();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error:" + ex.Message);
                    }
                }

                System.Environment.Exit(0);
            }
        }

    }
}
